#pragma once
#include "socket.hpp"
#include "Log.hpp"
#include "io_service.hpp"
#include <memory>
using namespace SocketModule;
using namespace LogModule;
class listener : public connection
{
public:
    listener(int port)
        : _tcp_sock(std::make_shared<TcpSocket>()), _port(port)
    {
        _tcp_sock->BuildTcpSocketMethod(port);
        set_fd(_tcp_sock->Fd());
        set_events(EPOLLIN | EPOLLET);
        LOG(LogLevel::INFO) << "listener create success" << " fd: " << _tcp_sock->Fd();
    }
    virtual void receiver() override
    {
        // LOG(LogLevel::DEBUG) << "hahahha Accepter";
        while (true)
        {
            InetAddr client_addr;
            int out_errno = 0;
            auto client = _tcp_sock->Accepter(&client_addr, out_errno);
            if (client != nullptr)
            {
                auto io = std::make_shared<io_service>(client->Fd());
                io->set_events(EPOLLIN | EPOLLET);
                io->RegisterOnMessage()
                owner()->insert_connection(*io);
                LOG(LogLevel::INFO) << "accept new connection: " << client->Fd() << " " << client_addr.Addr();
            }
            else
            {
                if (out_errno == EAGAIN || out_errno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accetper all connection ... done " << strerror(out_errno);
                    break;
                }
                else if(out_errno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accept interrupted " << strerror(out_errno);
                    continue;
                }
                else
                {
                    LOG(LogLevel::ERROR) << "accept error " << strerror(out_errno);
                    break;
                }
            }
        }
    }
    int fd()
    {
        return _tcp_sock->Fd();
    }

private:
    virtual void sender() override
    {
        // 监听器不需要发送数据
    }

    virtual void excepter() override
    {
        
    }

    std::shared_ptr<Socket> _tcp_sock;
    int _port;
};